package com.lb.sssq.service.imp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.edais.dao.RateRisesCouponsDao;
import com.edais.dao.UserChannelPointDao;
import com.edais.domain.UserChannelPoint;
import com.edais.domain.UserInfo;
import com.edais.service.LoanService;
import com.edais.service.UserService;
import com.edais.util.DateUtil;
import com.edais.util.DecimalFormatUtil;
import com.edais.util.FtpUtil;
import com.edais.util.LoginRedirectUtil;
import com.edais.util.NumberToCN;
import com.edais.util.StrUtil;
import com.lb.sssq.dao.DepositDao;
import com.lb.sssq.domain.Scattered_sssq;
import com.lb.sssq.service.DepositService;
import com.lb.sssq.util.Arrays;
import com.lb.sssq.util.CommonUtil;
import com.lb.sssq.util.Consts;
import com.lb.sssq.util.Message;
import com.lb.sssq.vo.IncomeStatementListVo;

import freemarker.template.Configuration;
import freemarker.template.Template;

@Service

@Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
public class DepositServiceImp implements DepositService {
	private static final Log logger = LogFactory.getLog(DepositServiceImp.class);

	@Autowired
	private DepositDao depositDao;
	
	@Autowired
	private RateRisesCouponsDao rateRisesCouponsDao;
	
	@Autowired
	private UserChannelPointDao userChannelPointDao;
	
	@Autowired
	private UserService userService;
	
	
	@Autowired
	private LoanService loanService;

	/**
	 * 查询余额宝详情
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,readOnly=false)
	public String queryMoneyFundDetail(Map<String, String> map) throws Exception{
		
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		String dayLimit = "";
		String transferLimit = "";
		String minimumTransferLimit = "";
		
		// 赎回限额
		/**
		 * 从BL后台数据库系统参数设置表转出限额
		 */
		List<String> listStr = new ArrayList<String>();//给sql传入的list参数
		
		listStr.add("single.day.out.limit");//单日转出限额
		listStr.add("single.transfer.limit");//单笔转出限额
		listStr.add("single.minimum.transfer.limit");//单笔最低转出限额
		List<Map<String, Object>> extractFeeRate = depositDao.queryParamName(listStr);//去BL查询系统参数表
		
		for(Map<String, Object> mapStr : extractFeeRate) {
			if("single.day.out.limit".equals(mapStr.get("NAME"))) {//单日转出限额
				dayLimit = mapStr.get("VALUE") + "";
			}else if("single.transfer.limit".equals(mapStr.get("NAME"))) {//单笔转出限额
				transferLimit = mapStr.get("VALUE") + "";
			}else if("single.minimum.transfer.limit".equals(mapStr.get("NAME"))) {//单笔最低转出限额
				minimumTransferLimit = mapStr.get("VALUE") + "";
			}
		}
		
		rtnMap.put("dayLimit", dayLimit); 
		rtnMap.put("transferLimit", transferLimit); 
		rtnMap.put("minimumTransferLimit", minimumTransferLimit); 
		
		// 查询余额宝类型的计划id
		Map<String, Object> queryMap = new HashMap<String,Object>();
		queryMap.put("mianPlanId", map.get("finaceId"));
		List<String> idList = depositDao.getPlanId(queryMap);
		if(null == idList || idList.size() <= 0){
			logger.error("未查询到相关产品");
			rtnMap.put("yesterdayGain", "0.00");            // 昨日收益
			rtnMap.put("currentIncome", "0.00");   // 在投收益
			rtnMap.put("accountAmount", "0.00");   // 在投金额
			rtnMap.put("incomeTotal", "0.00");   // 累计收益
			rtnMap.put("annualizedReturnRate", "0"); // 年化收益率
			rtnMap.put("adjustRate", "0"); // 调整利率上限
			rtnMap.put("couponsRateRises", "0"); // 当日加息利率
			rtnMap.put("signInRateRises", "0"); // 当日签到加息利率
			
			return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
		}
		// 今日年化收益率
		Map<String, Object> rateMap = depositDao.getExpectedRate(Arrays.toString(idList.toArray()));
		String expectedRate = "0";
		BigDecimal adjustRate = BigDecimal.ZERO;
		BigDecimal maxAdjustRate = BigDecimal.ZERO;
		if (rateMap != null) {
			expectedRate = rateMap.get("EXPECTED_RATE") == null ? "0" : rateMap.get("EXPECTED_RATE").toString();
			String rate = rateMap.get("MAX_ADJUST_RATE") == null ? "0" : rateMap.get("MAX_ADJUST_RATE").toString();
			maxAdjustRate = new BigDecimal(rate);
		}
		// 年化收益率
		rtnMap.put("annualizedReturnRate", expectedRate);
		
		if (StringUtils.isNotBlank(map.get("userId"))) {
			Map<String,Object> parm = new HashMap<String, Object>();
			parm.put("userId", map.get("userId"));
			UserChannelPoint userChannelPoint = userChannelPointDao.findChannelPointByParm(parm);
			if (userChannelPoint != null) {
				adjustRate = maxAdjustRate.multiply(
							new BigDecimal(userChannelPoint.getCurrentFloatRateChannel()));
			}
		}
		// 调整利率
		rtnMap.put("adjustRate", adjustRate.setScale(1, RoundingMode.DOWN));
		
		/**
		 * 调用核心接口 E360001查询投资收益（昨日收益,在投收益）
		 * */
		String transCode = "E360001";
		Map<String, Object> queryCoreMap = new HashMap<String,Object>();
		queryCoreMap.put("userId", map.get("userId"));
		queryCoreMap.put("planId", Arrays.toString(idList.toArray()));
		
		String jsonStr = CommonUtil.constructJsonStr(transCode, map.get("userId"),
				queryCoreMap);
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		if(Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))){
			rtnMap.put("yesterdayGain", jsonObject.get("earningsYesterday"));   // 昨日收益
			rtnMap.put("currentIncome", jsonObject.get("currentIncome"));   // 在投收益
		} else {
			logger.debug("=====E360001核心接口调用异常=====");
			logger.debug("rescode：" + jsonObject.getString("rescode") + "；  resmsg：" + jsonObject.getString("resmsg"));
			rtnMap.put("yesterdayGain", "0.00");            // 昨日收益
			rtnMap.put("currentIncome", "0.00");            // 在投收益
		}
		
		/**
		 * 调用核心接口 E360002查询投资收益（累计收益，在投金额）
		 * */
		transCode = "E360002";
		jsonStr = CommonUtil.constructJsonStr(transCode, map.get("userId"),
				queryCoreMap);
		rtnStr = CommonUtil.getCoreValue(jsonStr);
		jsonObject = JSONObject.fromObject(rtnStr);
		if(Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))){
			rtnMap.put("accountAmount", jsonObject.get("sumOrderValue"));   // 在投金额
			rtnMap.put("incomeTotal", jsonObject.get("sumIncome"));   // 累计收益
		} else {
			logger.debug("=====E360002核心接口调用异常=====");
			logger.debug("rescode：" + jsonObject.getString("rescode") + "；  resmsg：" + jsonObject.getString("resmsg"));
			rtnMap.put("accountAmount", "0.00");   // 在投金额
			rtnMap.put("incomeTotal", "0.00");   // 累计收益
		}
		
		//根据UserId查询用户活期订单ID 
		//根据用户ID查询用户在投活期订单
		transCode = "E310064";
		System.out.println(map.get("userId"));
		rtnMap.put("couponsRateRises", "0");
		rtnMap.put("signInRateRises", "0");
		if(StringUtils.isNotBlank(map.get("userId"))){
			queryCoreMap.put("userId", map.get("userId"));
			queryCoreMap.put("planId", "109");
			jsonStr = CommonUtil.constructJsonStr(transCode,
					null, queryCoreMap);
			rtnStr = CommonUtil.getCoreValue(jsonStr);
			jsonObject = JSONObject.fromObject(rtnStr);
			
			if(Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))){
				boolean existOrderId = Boolean.parseBoolean(jsonObject.getString("existOrderId"));
				//存在活期订单直接进行使用
				if(existOrderId){
					Long orderId = jsonObject.getLong("orderId");
					queryCoreMap.put("status", "1");
					queryCoreMap.put("productId","109");
					//queryCoreMap.put("useFlag", "1");
					queryCoreMap.put("orderId", orderId);
					//根据ID查询当日加息券利率
					DecimalFormat df = new DecimalFormat("#.#"); 
					BigDecimal rateRises = this.rateRisesCouponsDao.queryCurrentRateRiseByOrderId(queryCoreMap);//TODO 获取加息券利率
					BigDecimal signInRateRises = this.rateRisesCouponsDao.queryQdRateRiseByOrderId(queryCoreMap);//TODO 获取签到利率
					if (rateRises == null) {
						rateRises = BigDecimal.ZERO;
					}
					rtnMap.put("couponsRateRises", df.format(rateRises));
					rtnMap.put("signInRateRises", df.format(signInRateRises));
					
				}
			}
		}
		
		
		// 设置返回code
		return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
	}
	
	// 获取，在投金额
	@Override
	@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,readOnly=false)
	public String findAccountAmount(Map<String, String> map) throws Exception{
		
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		
		// 查询余额宝类型的计划id
		Map<String, Object> queryMap = new HashMap<String,Object>();
		queryMap.put("mianPlanId", map.get("finaceId"));
		
		List<String> idList = depositDao.getPlanId(queryMap);
		if(null == idList || idList.size() <= 0){
			logger.error("未查询到相关产品");
			rtnMap.put("accountAmount", "0.00");   // 在投金额
			return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
		}

		Map<String, Object> queryCoreMap = new HashMap<String,Object>();
		queryCoreMap.put("userId", map.get("userId"));
		queryCoreMap.put("planId", Arrays.toString(idList.toArray()));
	
		/**
		 * 调用核心接口 E360002查询投资收益（累计收益，在投金额）
		 * */
		String transCode = "E360002";
		String jsonStr = CommonUtil.constructJsonStr(transCode, map.get("userId").toString(), queryCoreMap);
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		if(Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))){
			rtnMap.put("accountAmount", jsonObject.get("sumOrderValue"));   // 在投金额
			rtnMap.put("currentIncome", jsonObject.get("currentIncome"));   // 在投收益
		} else {
			logger.debug("=====E360002核心接口调用异常=====");
			logger.debug("rescode：" + jsonObject.getString("rescode") + "；  resmsg：" + jsonObject.getString("resmsg"));
			rtnMap.put("accountAmount", "0.00");   // 在投金额
		}
		
		return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
	}
	
	
	/**
	 * 查询余额宝交易记录
	 */
	@Override
	public String queryMoneyFundFlow(Map<String, String> map) throws Exception {
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		
		//Add By ZuoJun For DepositServiceImpl RedisCache In 2016-4-5 Begin
		String userId =  map.get("userId");
//		String totalSize = (String) RedisOperateUtil.getString(RedisContant.KEY_TRANSFER_RECORD_PAGE_TOTALSIZE + userId);
		long current = Integer.parseInt(map.get("current"));
		long pageSize = Integer.parseInt(map.get("pageSize"));		
//		List<JSONObject> redisJSONObjs =  (List<JSONObject>) RedisOperateUtil.lrangeObjectForPage(RedisContant.KEY_TRANSFER_RECORD_PAGE + userId, current, pageSize);
		//需判断 RedisOperationUtil.setString()设置了过期时间		

//		if(totalSize != null && redisJSONObjs != null && redisJSONObjs.size() > 0){
//			rtnMap.put("totalNum", totalSize);
//			JSONArray array = new JSONArray();
//			for (JSONObject json: redisJSONObjs) {
//				array.add(json.toString());
//			}
//			rtnMap.put("list", array);				
//			rtnMap.put("listSize", redisJSONObjs.size());				
//			return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
//	
//		}
		//Add By ZuoJun For DepositServiceImpl RedisCache In 2016-4-5 End
		
		/**
		 * 调用核心接口 E360004查询余额宝交易记录
		 * */
		String transCode = "E360004";
		Map<String, Object> queryCoreMap = new HashMap<String,Object>();
		queryCoreMap.put("userId", map.get("userId"));
		queryCoreMap.put("current", map.get("current"));
		queryCoreMap.put("pageSize", map.get("pageSize"));
		queryCoreMap.put("fundType", map.get("fundType"));
		
		String jsonStr = CommonUtil.constructJsonStr(transCode, map.get("userId"),
				queryCoreMap);
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		if(Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))){
			String totalNum = jsonObject.get("totalNum").toString();
			rtnMap.put("totalNum", totalNum);
			rtnMap.put("list", jsonObject.get("list"));
			rtnMap.put("sysdate", DateUtil.getCurrentDateStr());
			rtnMap.put("listSize", jsonObject.get("listSize"));
			
			//Add By ZuoJun For DepositServiceImpl RedisCache In 2016-4-5 Begin
//			RedisOperateUtil.setString(RedisContant.KEY_TRANSFER_RECORD_PAGE_TOTALSIZE + userId, totalNum);
//			JSONArray jsonArr = jsonObject.getJSONArray("list");
//			if (jsonArr != null) {
//				for(int i = 0; i <jsonArr.size(); i++){
//					JSONObject json = jsonArr.getJSONObject(i);
//					RedisOperateUtil.rpushObject(RedisContant.KEY_TRANSFER_RECORD_PAGE + userId, json);
//				}
//			}			
			//Add By ZuoJun For DepositServiceImpl RedisCache In 2016-4-5 End
		} else {
			logger.debug("=====E360004核心接口调用异常=====");
			logger.debug("rescode：" + jsonObject.getString("rescode") + "；  resmsg：" + jsonObject.getString("resmsg"));
		}
		return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
	}
	
	@Override
	public String queryOrderCreditList(Map<String, String> map)
			throws Exception {
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		/**
		 * 调用核心接口 E360006查询当前在投债权及借款人信息
		 * */
		String transCode = "E360006";
		Map<String, Object> queryCoreMap = new HashMap<String,Object>();
		queryCoreMap.put("userId", map.get("userId"));
		queryCoreMap.put("current", map.get("current"));
		queryCoreMap.put("pageSize", map.get("pageSize"));
		queryCoreMap.put("planId", "109");
		
		String jsonStr = CommonUtil.constructJsonStr(transCode, map.get("userId"),
				queryCoreMap);
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		if(Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))){
			String totalNum = jsonObject.get("totalNum").toString();
			rtnMap.put("totalNum", totalNum);
			rtnMap.put("list", jsonObject.get("list"));
			rtnMap.put("sysdate", DateUtil.getCurrentDateStr());
			rtnMap.put("listSize", jsonObject.get("listSize"));
		} else {
			logger.debug("=====E360006核心接口调用异常=====");
			logger.debug("rescode：" + jsonObject.getString("rescode") + "；  resmsg：" + jsonObject.getString("resmsg"));
			rtnMap.put("totalNum", 0);
	    	rtnMap.put("listSize", 0);
	    	rtnMap.put("list", new ArrayList());
		}
		return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
	}
	
	@Override
	public List<Scattered_sssq> queryScatteredLoan(Map<String, Object> map) {
		return depositDao.queryScatteredLoan(map);
	}
	/**
	 * 根据(在售>预售>售罄 时间降序)获取1条上架活期标信息
	 * @param map
	 * @return
	 */
	@Override
	public Map<String,Object> queryScatteredLoanInfo(Map<String, Object> map) {
		
		List<Map<String,Object>> resultListMap = new ArrayList();
		
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		
		String userId = String.valueOf( map.get("userId"));
		
		List<Scattered_sssq> scatteredList = depositDao.queryScatteredLoanInfo(map);
		String totalNum = "1";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		Map<String, Object> map2 = new HashMap<String, Object>();
		String investUserNum = "";
		//ouyy 优化
		StringBuffer bidIdBf=new StringBuffer();
		for(int i =0;i<scatteredList.size();i++){
			bidIdBf.append(String.valueOf(scatteredList.get(i).getBidId())+",");
		}
		String bidId=bidIdBf.toString();
		Map<String,Object> listEx=null;
		
		if(bidId.lastIndexOf(",")!=-1){
			bidId=bidId.substring(0,bidId.lastIndexOf(","));
			logger.debug("queryDepositLoanLenderDetailCountEx传值参数-------"+bidId);
			map2.put("bidId", bidId);
			
			try {
				listEx = loanService.queryDepositLoanLenderDetailCountEx(map2);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			logger.debug("queryDepositLoanLenderDetailCountEx返回结果-------"+listEx);
		}
		//获取活期利率
		Map<String, Object> resMap = null;
		try {
			resMap = findCurrentRate(userId);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		String adjustRate = String.valueOf(resMap.get("adjustRate"));

		for(int i =0;i<scatteredList.size();i++){
			Scattered_sssq sc = scatteredList.get(i);
			Map<String,Object> scMap = new HashMap<String,Object>();
			scMap.put("productName", sc.getProductName());
			scMap.put("annualRate", sc.getAnnualRate());
			scMap.put("remanAmount", sc.getRemanAmount());
			scMap.put("saleTotalAmount", sc.getSaleTotalAmount());
			scMap.put("endSaleTime", sc.getEndSaleTime()==null?"":sdf.format(sc.getEndSaleTime()));
			scMap.put("investMinAmount", sc.getInvestMinAmount());
			scMap.put("finishedRatio", DecimalFormatUtil.getDecimalFormat0(BigDecimal.ONE.compareTo(sc.getFinishedRatio())>0 && BigDecimal.ZERO.compareTo(sc.getFinishedRatio())<0?BigDecimal.ONE:sc.getFinishedRatio()));
			scMap.put("id", sc.getId());
			scMap.put("loanId", sc.getBidId());
			//调整利率
			scMap.put("adjustRate", adjustRate);
			
			// 获取标的列表人数
			if(listEx!=null&&listEx.size()!=0&&listEx.size()==scatteredList.size()){
				if(listEx.containsKey(String.valueOf(sc.getBidId()))){
					scMap.put("investUserNum", listEx.get(String.valueOf(sc.getBidId())));
				}else{
					scMap.put("investUserNum", "1");
				}
			}else{
				map2.put("loanId", sc.getBidId());
				try {
					investUserNum = loanService.queryDepositLoanLenderDetailCount(map2);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				scMap.put("investUserNum", investUserNum);
			}
			//guanxuxing 返回时间  begin
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");	
			int day = 0;
			int hour = 0;
			int min = 0;
			int sec = 0;
		
			Date dateTime=sc.getStartSellingTime();   //产品上架时间
			logger.info("[上架时间]====>"+df.format(dateTime));
			logger.info("[当前时间]====>"+df.format(new Date(System.currentTimeMillis())));
			long time1 = System.currentTimeMillis();  //当前时间
			long time2 = dateTime.getTime();          //上架时间
			logger.info("[当前time1]-->"+time1);
			logger.info("[上架time2]-->"+time2);
			long diff=time2-time1;
			
			day = (int) (diff / (24 * 60 * 60 * 1000));
			hour = (int) (diff / (60 * 60 * 1000) - day * 24);
			min = (int) ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
			sec = (int) (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);	
			if(diff < 0){
				day = 0;  hour = 0;  min = 0; sec = 0;
			}
			logger.info("[上架时间距离当前时间]-->" + day + "天" + hour + "小时" + min + "分"
					+ sec + "秒");
			
			scMap.put("day", day);
			scMap.put("hour", hour);
			scMap.put("min", min);
			scMap.put("sec", sec);
			//guanxuxing 返回时间  end
			scMap.put("startSellingTime", sc.getStartSellingTime()==null?"":sdf.format(sc.getStartSellingTime()));	
			
			resultListMap.add(scMap);			
		}				
				
		rtnMap.put("totalNum", totalNum);
		rtnMap.put("investUserNum", investUserNum);
		rtnMap.put("listSize", String.valueOf(resultListMap.size()));
		rtnMap.put("list", resultListMap);	
		rtnMap.put("resmsg_cn", "");
		
		return rtnMap;
	}
	
	@Override
	public String queryScatteredLoanCount(Map<String, Object> map) {
		return depositDao.queryScatteredLoanCount(map);
	}
	/**
	 * 根据(在售>预售>售罄 时间降序)获取1条上架活期标信息总条数
	 * @param map
	 * @return
	 */
	@Override
	public String queryScatteredLoanInfoCount(Map<String, Object> map) {
		return depositDao.queryScatteredLoanInfoCount(map);
	}
	
	/**
	 * 查询余额宝历史收益列表
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,readOnly=false)
	public String queryIncomeStatementList(Map<String, Object> map) throws Exception{
		
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		
		// 查询余额宝类型的计划id
		Map<String, Object> queryMap = new HashMap<String,Object>();
		queryMap.put("mianPlanId", map.get("finaceId"));
		List<String> idList = depositDao.getPlanId(queryMap);
		if(null == idList || idList.size() <= 0){
			logger.error("未查询到相关产品");
			rtnMap.put("totalNum", 0);
	    	rtnMap.put("listSize", 0);
	    	rtnMap.put("list", new ArrayList());
			return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
		}
		/* Redis取出活期理财 昨日收益（收益明细列表）数据 */
		String userId = map.get("userId").toString();
		long currentPage = Integer.parseInt(map.get("current").toString());
		long pageSize = Integer.parseInt(map.get("pageSize").toString());
//		String totalSize = (String) RedisOperateUtil
//				.getString(RedisContant.KEY_INVEST_CURRENT_PROFIT_LIST_PAGE_TOTALSIZE
//						+ userId);
//		List<IncomeStatementListVo> redisIncomeStatementVoList = (List<IncomeStatementListVo>) RedisOperateUtil
//				.lrangeObjectForPage(
//						RedisContant.KEY_INVEST_CURRENT_PROFIT_LIST_PAGE
//								+ userId, currentPage, pageSize);

//		if (totalSize != null && redisIncomeStatementVoList != null
//				&& redisIncomeStatementVoList.size() > 0) {
//			rtnMap.put("totalNum", totalSize);
//			rtnMap.put("listSize", redisIncomeStatementVoList.size());
//			rtnMap.put("list", redisIncomeStatementVoList);
//			// 设置返回code
//			return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE,
//					Consts.SUCCESS_DESCRIBE, "");
//
//		}
		/**
		 * 调用核心接口 E360001查询投资收益明细
		 * */
		String transCode = "E360001";
		Map<String, Object> queryCoreMap = new HashMap<String,Object>();
		queryCoreMap.put("userId", map.get("userId"));
		queryCoreMap.put("planId", Arrays.toString(idList.toArray()));
		queryCoreMap.put("pageSize", map.get("pageSize"));
		queryCoreMap.put("current", map.get("current"));
		
		String jsonStr = CommonUtil.constructJsonStr(transCode, map.get("userId").toString(),
				queryCoreMap);
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		if(Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))){
			List<IncomeStatementListVo> incomeStatementVoList = new ArrayList<IncomeStatementListVo>();
			Long totalNum = jsonObject.getLong("totalNum");
			if(totalNum>0){
				JSONArray jsonArr = jsonObject.getJSONArray("list");
				if(jsonArr != null && jsonArr.size() > 0){
					for(int i = 0; i < jsonArr.size(); i++){
						JSONObject jsonObj = jsonArr.getJSONObject(i);
						IncomeStatementListVo incomeStatementListVo = new IncomeStatementListVo();
						incomeStatementListVo.setEarningsDate(jsonObj.getString("incomeDay"));
						incomeStatementListVo.setIncomeAmount(jsonObj.getString("incomeAmount"));
						incomeStatementListVo.setOndayIncomeAmount(jsonObj.getString("ondayIncomeAmount"));
						incomeStatementListVo.setNormalIncomeAmount(jsonObj.getString("normalIncomeAmount"));
						incomeStatementVoList.add(incomeStatementListVo);
					}
				}
				rtnMap.put("totalNum", jsonObject.getLong("totalNum"));
		    	rtnMap.put("listSize", incomeStatementVoList.size());
		    	rtnMap.put("list", incomeStatementVoList);
		    	/* Redis存入活期理财 昨日收益（收益明细列表） */
//				RedisOperateUtil
//						.setString(
//								RedisContant.KEY_INVEST_CURRENT_PROFIT_LIST_PAGE_TOTALSIZE
//										+ map.get("userId").toString(),
//								jsonObject.getLong("totalNum") + "");
//				RedisOperateUtil.rpushObjectAll(
//						RedisContant.KEY_INVEST_CURRENT_PROFIT_LIST_PAGE
//								+ map.get("userId").toString(),
//						incomeStatementVoList);
			}else{
				rtnMap.put("totalNum", 0);
		    	rtnMap.put("listSize", 0);
		    	rtnMap.put("list", new ArrayList());
			}
		} else {
			logger.debug("=====E360001核心接口调用异常=====");
			logger.debug("rescode：" + jsonObject.getString("rescode") + "；  resmsg：" + jsonObject.getString("resmsg"));
			rtnMap.put("totalNum", 0);
	    	rtnMap.put("listSize", 0);
	    	rtnMap.put("list", new ArrayList());
		}
		
		// 设置返回code
		return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
	}
	
	/**
	 * 转出接口
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,readOnly=false)
	public String updateInvestmentAmount(Map<String, Object> map) throws Exception{
		
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		
		// 查询余额宝类型的计划id
		Map<String, Object> queryMap = new HashMap<String,Object>();
		queryMap.put("mianPlanId", map.get("finaceId"));
		List<String> idList = depositDao.getPlanId(queryMap);
		if(null == idList || idList.size() <= 0){
			logger.error("未查询到相关产品");
			rtnMap.put("totalNum", 0);
	    	rtnMap.put("listSize", 0);
	    	rtnMap.put("list", new ArrayList());
			return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
		}
		
		/**
		 * 调用核心接口 E360003转出操作
		 * */
		//String transCode = "E360003";
		String transCode = "E360015";//转出优化版
		Map<String, Object> queryCoreMap = new HashMap<String,Object>();
		queryCoreMap.put("userId", map.get("userId"));
		queryCoreMap.put("planId", Arrays.toString(idList.toArray()));
		queryCoreMap.put("turnOutAmount", map.get("turnOutAmount"));
		
		String jsonStr = CommonUtil.constructJsonStr(transCode, map.get("userId").toString(),
				queryCoreMap);
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		if(Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))){
			// 设置返回code
			return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
		} else {
			String rescode = Consts.ERROR_CODE;
			String resmsg = Message.CnDescriptionExpression.EXIT_AMOUNT_FAILED;
			
			if("run.time.error".equals(jsonObject.get("resmsg"))){
				rescode = Consts.CHECK_CODE;
				resmsg = Message.CnDescriptionExpression.EXIT_AMOUNT_FAILED_TIME;
			}else if("orderValue.is.not.enough".equals(jsonObject.get("resmsg"))){
				rescode = Consts.CHECK_CODE;
				resmsg = Message.CnDescriptionExpression.EXIT_AMOUNT_FAILED_MONEY;
			}else if("single.day.out.limit".equals(jsonObject.get("resmsg"))){
				rescode = Consts.CHECK_CODE;
				resmsg = Message.CnDescriptionExpression.EXIT_AMOUNT_FAILED_SINGLEDAY;
			}else if("single.transfer.limit".equals(jsonObject.get("resmsg"))){
				rescode = Consts.CHECK_CODE;
				resmsg = Message.CnDescriptionExpression.EXIT_AMOUNT_FAILED_SINGLETRANSFER;
			}else if("single.minimum.transfer.limit".equals(jsonObject.get("resmsg"))){
				rescode = Consts.CHECK_CODE;
				resmsg = Message.CnDescriptionExpression.EXIT_AMOUNT_FAILED_SINGLEMINIMUM;
			}
			//logger.error("=====E360003核心接口调用异常=====");
			logger.error("=====E360015核心接口调用异常=====");
			logger.error("rescode = " + rescode + " resmsg=" + resmsg);
			// 设置返回code
			return CommonUtil.setResultStringCn(rtnMap, rescode, "",resmsg);
		}
	}
	
	@Override
	public String queryMyAccountDetail(Map<String, String> map)
			throws Exception {
		/**
		 * 调用核心接口 E360008查询我的账户详情信息
		 * */
		String transCode = "E360008";
		Map<String, Object> queryCoreMap = new HashMap<String, Object>();
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		queryCoreMap.put("userId", map.get("userId"));
	
		String jsonStr = CommonUtil.constructJsonStr(transCode,
				map.get("userId").toString(), queryCoreMap);
		
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		
		if (Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))) {
			rtnMap.put("accountDetail", jsonObject.get("accountDetail"));
		} else {
			logger.debug("=====E360008核心接口调用异常=====");
			logger.debug("rescode：" + jsonObject.getString("rescode")
					+ "；  resmsg：" + jsonObject.getString("resmsg"));
			rtnMap.put("accountDetail", new JSONObject());
		}
		return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE,
				Consts.SUCCESS_DESCRIBE, "");
	}
	
	@Override
	public String queryInvestAmount(Map<String, String> map)
			throws Exception {
		/**
		 * 调用核心接口 E350006查询订单映射表标的对应的金额
		 * */
		String transCode = "E350006";
		Map<String, Object> queryCoreMap = new HashMap<String, Object>();
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		queryCoreMap.put("orderId", map.get("orderId"));
		queryCoreMap.put("bidId", map.get("bidId"));

		String jsonStr = CommonUtil.constructJsonStr(transCode,
				"", queryCoreMap);
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		
		if (Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))) {
			rtnMap.put("investAmount", jsonObject.get("investAmount"));
			rtnMap.put("userId", jsonObject.get("userId"));
		} else {
			logger.debug("=====E350006核心接口调用异常=====");
			logger.debug("rescode：" + jsonObject.getString("rescode")
					+ "；  resmsg：" + jsonObject.getString("resmsg"));
			rtnMap.put("investAmount", new JSONObject());
		}
		return CommonUtil.setResultStringCn(rtnMap, Consts.SUCCESS_CODE,
				Consts.SUCCESS_DESCRIBE, "");
	}

	@Override
	public Map<String, Object> getExpectedRate(String finaceId) throws Exception {
		Map<String, Object> rtnMap = new HashMap<String, Object>();
		// 查询余额宝类型的计划id
		Map<String, Object> queryMap = new HashMap<String,Object>();
		queryMap.put("mianPlanId", finaceId);
		List<String> idList = depositDao.getPlanId(queryMap);
		if(null == idList || idList.size() <= 0){
			logger.error("未查询到相关产品");
			rtnMap.put("annualizedReturnRate", "0"); // 年化收益率
			rtnMap.put("maxAdjustRate", "0"); // 调整利率上限
			return rtnMap;
		}
		// 今日年化收益率
		Map<String, Object> map = depositDao.getExpectedRate(Arrays.toString(idList.toArray()));
		String expectedRate = "0";
		String maxAdjustRate = "0";
		if (map != null) {
			expectedRate = map.get("EXPECTED_RATE") == null ? "0" : map.get("EXPECTED_RATE").toString();
			maxAdjustRate = map.get("MAX_ADJUST_RATE") == null ? "0" : map.get("MAX_ADJUST_RATE").toString();
		}
		rtnMap.put("annualizedReturnRate", expectedRate); // 年化收益率
		rtnMap.put("maxAdjustRate", maxAdjustRate); // 年化收益率

		return rtnMap;
	}
	
	/**
	 * 生成借款协议
	 * 
	 * */
	public void createAgreement(String userId,BigDecimal decBuyAmount, String bidId, String orderId) {
		//=======================生成借款协议start by jiangbo=======================
		InputStream fileInputStream = null;//文件输入流
		try {
			String path = LoginRedirectUtil.agreementPath; 
			Configuration cfg = new Configuration();
			//通过userID获取user信息
			UserInfo userInfo = this.userService.getUserInfo(userId);

			cfg.setDirectoryForTemplateLoading(new File(path+"/agreement/ftl/"));  //设置读取模板文件的目录
			Template t = cfg.getTemplate("creditoTranAgreement.ftl");  //读取文件名为Test.ftl的模板
			//存储数据
			Map<String, Object> maps = new HashMap<String, Object>();  
			if(userInfo != null) {
				if(StringUtils.isNotEmpty(userInfo.getId_card())) {
					maps.put("idCard", userInfo.getId_card());
				}else {
					maps.put("idCard", "");
				}
			}else {
				maps.put("idCard", "");
			}
	        //ouyy 修改金额小数保留两位
			String investAmount="";
	        try {
	        	investAmount=CommonUtil.setFormatMoney(String.valueOf(decBuyAmount));
			} catch (Exception e) {
				// TODO: handle exception
				investAmount=String.valueOf(decBuyAmount);
			}
			//购买金额
			maps.put("buyAmount", investAmount); 
			//购买金额大写
			maps.put("buyAmount_big", NumberToCN.number2CNMontrayUnit(decBuyAmount));
			//年化收益
			maps.put("interest", this.getExpectedRate("109"));
			//ouyy 增加用户名
			maps.put("userName", userInfo.getReal_name());
			
			//通过资产部id获取标的id
			//String bidId = this.depositService.queryBidIdByFinaceId(finaceId);
			
			Writer out = new OutputStreamWriter(new FileOutputStream(
					path+"/agreement/html/"+StrUtil.fileNameMD5(orderId+bidId)+".html"), "utf-8");  //输出流
			t.process(maps, out); //动态加载root中的数据到Test.html。数据在模板中定义好了。
			out.close();
			
			FtpUtil fu = new FtpUtil();
			String fileName = StrUtil.fileNameMD5(orderId+bidId)+".html";//文件名称
			String str = null;//文件输入流
			//File f1 = new File(realPath + File.separator + imageFileName);
			File f1 = new File(path+"/agreement/html/"+StrUtil.fileNameMD5(orderId+bidId)+".html");
				try {
					fileInputStream = new FileInputStream(f1);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			//1.传入输入流(成功)
			//fu.uploadFileInputStream(fileName,fileInputStream);
			//2.传入字符串
			//str = fu.inputStream2String(fileInputStream);
			//str = fu.inputStream2String2(fileInputStream);
			//fu.uploadString(fileName,str);
			//3.传入字节(成功)
			byte[] in2b= fu.input2byte(fileInputStream);
			fu.uploadByteAgreement(fileName,in2b,
//					"",
//					"ftpuser",
//					"ftpuser",
//					"");
					this.userService.getSystemSettingValue(com.edais.util.Consts.SystemSettingUpload.FTP_AGREEMENT_URL),
					this.userService.getSystemSettingValue(com.edais.util.Consts.SystemSettingUpload.FTP_AGREEMENT_NAME),
					this.userService.getSystemSettingValue(com.edais.util.Consts.SystemSettingUpload.FTP_AGREEMENT_PWD),
					this.userService.getSystemSettingValue(com.edais.util.Consts.SystemSettingUpload.FTP_AGREEMENT_PATH));
		} catch (Exception e) {
			logger.info("接口协议生成失败异常"+e.getCause());
		}finally{
			if(fileInputStream != null){
				try {
					fileInputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					logger.error("createAgreement接口关闭流发生异常---------"+e.getCause());
				}
			}
		}
	}

	@Override
	public String queryBidIdByFinaceId(String finaceId) {
		return this.depositDao.queryBidIdByFinaceId(finaceId);
	}

	/**
	 * 生成借款协议(传两台FTP服务器)
	 * 
	 * */
	public void createAgreement(String userId,BigDecimal decBuyAmount, String bidId, String orderId,String arrayStr,String investDateStr) {
		//=======================生成借款协议start by jiangbo=======================
		InputStream fileInputStream = null;//文件输入流
		try {
			String path = LoginRedirectUtil.agreementPath; 
			Configuration cfg = new Configuration();
			//通过userID获取user信息
			UserInfo userInfo = this.userService.getUserInfo(userId);

			cfg.setDirectoryForTemplateLoading(new File(path+"/agreement/ftl/"));  //设置读取模板文件的目录
			Template t = cfg.getTemplate("creditoTranAgreement.ftl");  //读取文件名为Test.ftl的模板
			//存储数据
			Map<String, Object> maps = new HashMap<String, Object>();  
			if(userInfo != null) {
				if(StringUtils.isNotEmpty(userInfo.getId_card())) {
					maps.put("idCard", userInfo.getId_card());
				}else {
					maps.put("idCard", "");
				}
			}else {
				maps.put("idCard", "");
			}
	        //ouyy 修改金额小数保留两位
			String investAmount="";
	        try {
	        	investAmount=CommonUtil.setFormatMoney(String.valueOf(decBuyAmount));
			} catch (Exception e) {
				// TODO: handle exception
				investAmount=String.valueOf(decBuyAmount);
			}
			//购买金额
			maps.put("buyAmount", investAmount); 
			//购买金额大写
			maps.put("buyAmount_big", NumberToCN.number2CNMontrayUnit(decBuyAmount));
			//年化收益
			maps.put("interest", this.getExpectedRate("109"));
			//ouyy 增加用户名
			maps.put("userName", userInfo.getReal_name());
			
			//通过资产部id获取标的id
			//String bidId = this.depositService.queryBidIdByFinaceId(finaceId);
			
			Writer out = new OutputStreamWriter(new FileOutputStream(
					path+"/agreement/html/"+StrUtil.fileNameMD5(orderId+bidId)+".html"), "utf-8");  //输出流
			t.process(maps, out); //动态加载root中的数据到Test.html。数据在模板中定义好了。
			out.close();
			
			FtpUtil fu = new FtpUtil();
			String fileName = StrUtil.fileNameMD5(orderId+bidId)+".html";//文件名称
			String str = null;//文件输入流
			//File f1 = new File(realPath + File.separator + imageFileName);
			File f1 = new File(path+"/agreement/html/"+StrUtil.fileNameMD5(orderId+bidId)+".html");
				try {
					fileInputStream = new FileInputStream(f1);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			//1.传入输入流(成功)
			//fu.uploadFileInputStream(fileName,fileInputStream);
			//2.传入字符串
			//str = fu.inputStream2String(fileInputStream);
			//str = fu.inputStream2String2(fileInputStream);
			//fu.uploadString(fileName,str);
			//3.传入字节(成功)
			byte[] in2b= fu.input2byte(fileInputStream);
			String ftpUrl=this.userService.getSystemSettingValue(com.edais.util.Consts.SystemSettingUpload.FTP_AGREEMENT_PATH);
			ftpUrl=ftpUrl.substring(0, ftpUrl.length()-1);
			fu.uploadByteAgreement(fileName,in2b,
//					"",
//					"ftpuser",
//					"ftpuser",
//					"");
					arrayStr,
					this.userService.getSystemSettingValue(com.edais.util.Consts.SystemSettingUpload.FTP_AGREEMENT_NAME),
					this.userService.getSystemSettingValue(com.edais.util.Consts.SystemSettingUpload.FTP_AGREEMENT_PWD),
					ftpUrl+"_"+investDateStr+"/");
		} catch (Exception e) {
			logger.info("接口协议生成失败异常"+e.getCause());
		}finally{
			if(fileInputStream != null){
				try {
					fileInputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					logger.error("createAgreement接口关闭流发生异常---------"+e.getCause());
				}
			}
		}
	}
	
	
	@Override
	public Map<String, Object> findCurrentRate(String userId) throws Exception {
		Map<String, Object> restMap = new HashMap<String,Object>();
		// 查询余额宝类型的计划id
		Map<String, Object> queryMap = new HashMap<String,Object>();
		queryMap.put("mianPlanId", "1");
		List<String> idList = depositDao.getPlanId(queryMap);
		if(null == idList || idList.size() <= 0){
			logger.error("未查询到相关产品");
			restMap.put("annualizedReturnRate", "0");
			restMap.put("adjustRate", "0");
			restMap.put("rescode", Consts.CHECK_CODE);
			restMap.put("resmsg_cn", "未查询到相关产品");
			return restMap;
		}
		
		// 今日年化收益率
		Map<String, Object> rateMap = depositDao.getExpectedRate(Arrays.toString(idList.toArray()));
		String expectedRate = "0";
		BigDecimal adjustRate = BigDecimal.ZERO;
		BigDecimal maxAdjustRate = BigDecimal.ZERO;
		if (rateMap != null) {
			expectedRate = rateMap.get("EXPECTED_RATE") == null ? "0" : rateMap.get("EXPECTED_RATE").toString();
			String rate = rateMap.get("MAX_ADJUST_RATE") == null ? "0" : rateMap.get("MAX_ADJUST_RATE").toString();
			maxAdjustRate = new BigDecimal(rate);
		}
		// 年化收益率
		restMap.put("annualizedReturnRate", expectedRate);
		if (userId != null && !"".equals(userId) && !"null".equals(userId)) {
			Map<String,Object> parm = new HashMap<String, Object>();
			parm.put("userId", userId);
			UserChannelPoint userChannelPoint = userChannelPointDao.findChannelPointByParm(parm);
			if (userChannelPoint != null) {
				adjustRate = maxAdjustRate.multiply(
							new BigDecimal(userChannelPoint.getCurrentFloatRateChannel()));
			}
		}
		// 调整利率
		restMap.put("adjustRate", adjustRate.setScale(1, RoundingMode.DOWN));
		restMap.put("rescode", Consts.SUCCESS_CODE);
		restMap.put("resmsg_cn", "");

		return restMap;
	}
	
	@Override
	public String getInvestYearAndMon(String orderId,String bidId) throws Exception {
		
		String investDateStr="";
		//调用核心接口 E350006查询订单投资日期
		String transCode = "E350006";
		Map<String, Object> queryCoreMap = new HashMap<String, Object>();
		queryCoreMap.put("orderId", orderId);
		queryCoreMap.put("bidId", bidId);

		String jsonStr = CommonUtil.constructJsonStr(transCode,
				"", queryCoreMap);
		String rtnStr = CommonUtil.getCoreValue(jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(rtnStr);
		
		if (Consts.SUCCESS_CODE.equals(jsonObject.get("rescode"))) {
			investDateStr=jsonObject.getString("investTime");
			investDateStr=investDateStr.replace("-", "");
			investDateStr=investDateStr.substring(2, 6);
		} else {
			logger.info("=====E350006核心接口调用（订单债权映射关系）查询异常=====");
			logger.info("rescode：" + jsonObject.getString("rescode")
					+ "；  resmsg：" + jsonObject.getString("resmsg"));
			throw new RuntimeException("");
		}
		return investDateStr;
	}
}
